package com.qkl.xiatang.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qkl.xiatang.app.config.AppConfig;
import com.qkl.xiatang.app.dto.BusinessDTO;
import com.qkl.xiatang.app.dto.WeatherDTO;
import com.qkl.xiatang.app.entity.CompanyEntity;
import com.qkl.xiatang.app.entity.WeatherEntity;
import com.qkl.xiatang.app.mapper.CompanyMapper;
import com.qkl.xiatang.app.mapper.WeatherMapper;
import com.qkl.xiatang.app.utils.AppSessionUtils;
import com.qkl.xiatang.app.utils.HttpResponse;
import com.qkl.xiatang.app.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
@Slf4j
public class WeatherService {

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private WeatherMapper weatherMapper;

    @Autowired
    private CompanyMapper companyMapper;

    private static Set<String> daysSet = new HashSet<>();
    static {
        daysSet.add("3");
        daysSet.add("7");
        daysSet.add("10");
        daysSet.add("15");
        daysSet.add("30");
    }

    /**
     *天气查询
     * @param lngString 经度
     * @param latString 纬度
     * @return
     */
    public BusinessDTO<Object> queryWeather(String lngString,String latString,String days){
        log.info("=====queryWeather lng={},lat={},days={}",lngString,latString,days);
        if( !daysSet.contains(days)){
            return BusinessDTO.failBusiness("非法参数");
        }
        String companyId = AppSessionUtils.getCompanyId();
        CompanyEntity companyEntity = companyMapper.selectById(companyId);
        if(null == companyEntity){
            return BusinessDTO.failBusiness("用户未选择公司");
        }
        Double lng = companyEntity.getLng();
        Double lat  = companyEntity.getLat();
        if(null == lng || null == lat || lng == 0.0 || lat == 0.0){
            return BusinessDTO.failBusiness("公司未定位");
        }

        String lngKey = getCacheKey(lng);
        String latKey = getCacheKey(lat);
        WeatherDTO weatherDTO = this.queryWeatherDB(lngKey,latKey,days);
        if(null == weatherDTO){
            BusinessDTO<WeatherDTO> busDTO = this.getWeather(String.valueOf(lng),String.valueOf(lat),days);
            if(!busDTO.isSucess()){
                return BusinessDTO.failBusiness(busDTO.getMessage());
            }
            weatherDTO = busDTO.getBusinessObject();
            this.addWeather(lngKey,latKey,days,weatherDTO.getData());
        }
        Map<String,Object> map = new HashMap<>();
        map.put("daily",weatherDTO.getDaily());
        return  BusinessDTO.sucessBusiness(map,"天气查询");
    }

   private BusinessDTO<WeatherDTO> getWeather(String lng,String lat,String days){
       String location = lng + "," + lat;
       String url = appConfig.getWeatherUrl() + days + "d";
       String key = appConfig.getWeatherKey();
       Map<String,Object> params = new HashMap<>();
       params.put("location",location);
       params.put("key",key);

       HttpResponse response =  HttpUtils.getRequest(url,params);
       String data = (String) response.getData();
       if(response.isSuccess()){
           WeatherDTO weatherDTO = JSON.parseObject(data,WeatherDTO.class);
           if(weatherDTO.isOK() && ObjectUtils.isNotEmpty(weatherDTO.getDaily())){
               weatherDTO.setData(data);
              return BusinessDTO.sucessBusiness(weatherDTO);
           }
       }
       return BusinessDTO.failBusiness("天气查询失败");
   }

   private void addWeather(String lng,String lat,String days,String data){
       WeatherEntity entity = new WeatherEntity();
       entity.setDaily(data);
       entity.setDays(days);
       entity.setCreateTime(new Date());
       entity.setLat(lat);
       entity.setLng(lng);
       weatherMapper.insert(entity);
   }

   private  WeatherDTO queryWeatherDB(String lng,String lat,String days){
       Calendar calendar = Calendar.getInstance();
       calendar.add(Calendar.MINUTE,-30);
       QueryWrapper queryWrapper = new QueryWrapper<WeatherEntity>().eq("lng",lng).eq("lat",lat).eq("days",days);
       queryWrapper.gt("create_time",calendar.getTime());
       queryWrapper.orderByDesc("create_time");
       List<WeatherEntity>  list = weatherMapper.selectList(queryWrapper);
       if(ObjectUtils.isNotEmpty(list)){
           return JSON.parseObject(list.get(0).getDaily(),WeatherDTO.class);
       }
       return null;
   }

    private static final String FORMAT = "%.4f";
    private static String getCacheKey(String s){
        return getCacheKey(parseDouble(s));
    }
    private static String getCacheKey(Double d){
        if(null == d){
            return "";
        }
        return String.format(FORMAT, d);
    }


    private static Double parseDouble(String s){
        if(StringUtils.isNotEmpty(s)){
            try{
                return Double.valueOf(s);
            }catch (Exception e){

            }
        }
        return null;
    }


}
